package storage

import (
	"time"
	"gopkg.in/square/go-jose.v2"
	"errors"

	"github.com/ingopansa/userinfoservice/model"
)

var (
	// ErrNotFound is the error returned by storages if a resource cannot be found.
	ErrNotFound = errors.New("not found")

	// ErrAlreadyExists is the error returned by storages if a resource ID is taken during a create.
	ErrAlreadyExists = errors.New("ID already exists")
)

type Storage interface {
	Close() error

	GetKeys() (Keys, error)
	UpdateKeys(updater func(old Keys) (Keys, error)) error

	GetUser(sub string)(model.User, error)	// gets a user by the users subject
	AddUser(user model.User)(error)
	ListUsers()([]model.User, error)
}

// VerificationKey is a rotated signing key which can still be used to verify
// signatures.
type VerificationKey struct {
	PublicKey *jose.JSONWebKey `json:"publicKey"`
	Expiry    time.Time        `json:"expiry"`
}

// Keys hold encryption and signing keys.
type Keys struct {
	// Key for creating and verifying signatures. These may be nil.
	SigningKey    *jose.JSONWebKey
	SigningKeyPub *jose.JSONWebKey

	// Old signing keys which have been rotated but can still be used to validate
	// existing signatures.
	VerificationKeys []VerificationKey

	// The next time the signing key will rotate.
	//
	// For caching purposes, implementations MUST NOT update keys before this time.
	NextRotation time.Time
}

